package vip.liux.backend.infrastructure.jpa.pay;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import vip.liux.contracts.models.pay.PayApp;
import vip.liux.contracts.repositories.pay.PayAppRepository;
import vip.liux.contracts.shared.enums.Status;

import java.time.LocalDateTime;

public interface PayAppJpaRepository extends JpaRepository<PayApp, Long>, PayAppRepository, JpaSpecificationExecutor<PayApp> {
    @Transactional
    @Query("update PayApp p set p.status = ?2 where p.id = ?1")
    @Modifying
    @Override
    void updateStatusById(Long id, Status status);

    @Override
    default Page<PayApp> findByPageList(String appKey, String name, Status status, LocalDateTime start, LocalDateTime end, Pageable page) {
        return findAll((root, query, criteriaBuilder) -> {
            var predicates = criteriaBuilder.conjunction();

            if (StringUtils.isNotBlank(appKey)) {
                predicates = criteriaBuilder.and(predicates, criteriaBuilder.equal(root.get("appKey"), appKey));
            }
            if (StringUtils.isNotBlank(name)) {
                predicates = criteriaBuilder.and(predicates, criteriaBuilder.like(root.get("name"), "%" + name + "%"));
            }
            if (status != null) {
                predicates = criteriaBuilder.and(predicates, criteriaBuilder.equal(root.get("status"), status));
            }
            if (start != null) {
                predicates = criteriaBuilder.and(predicates, criteriaBuilder.greaterThanOrEqualTo(root.get("creationTime"), start));
            }
            if (end != null) {
                predicates = criteriaBuilder.and(predicates, criteriaBuilder.lessThanOrEqualTo(root.get("creationTime"), end));
            }
            return predicates;
        }, PageRequest.of(page.getPageNumber(), page.getPageSize()));
    }
}